package org.shan.lis.shy;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Ascii;
import gnu.io.SerialPort;
import org.shan.lis.common.model.PersonResult;
import org.shan.lis.common.serial.IReciver;
import org.shan.lis.common.serial.Serial;
import org.shan.lis.shy.handler.ShyDataHandler;
import org.shan.lis.utils.AsciiUtils;
import org.shan.lis.utils.ByteBuffUtils;
import org.shan.lis.utils.LogUtils;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;

/**
 * Created by amanda.shan on 2019-07-05.
 */
public class ShySerial extends Serial {

    enum State {
        START, END, DATA;
    }

    private ByteBuffer buffer;

    private State state = State.END;

    private ShyDataHandler lisDataHandler;

    private ShyDataLis shyDataLis;

    public ShySerial(String portName) {
        this(portName, 9600);
    }

    public ShySerial(String portName, int baudRate) {
        super(portName, baudRate, SerialPort.PARITY_EVEN, SerialPort.FLOWCONTROL_RTSCTS_IN);

        buffer = ByteBuffUtils.initBuffer(10000);

        setReciver(new IReciver() {
            @Override
            public void recive(byte[] bs, int len) {

                LogUtils.d(AsciiUtils.bytesToAscii(bs, 0, len));

                ByteBuffUtils.addBytes(buffer, bs, len);
                try {
                    ShySerial.this.process();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void setShyDataLis(ShyDataLis shyDataLis) {
        this.shyDataLis = shyDataLis;
    }

    public void process() throws IOException {

        while (ByteBuffUtils.getSize(buffer) > 0) {

            if (state.equals(State.DATA)) {

                boolean end = lisDataHandler.decode(buffer);
                if (end) {
                    state = State.START;
                    ack();
                }
            } else {
                byte b = ByteBuffUtils.getByte(buffer);

                switch (b) {
                    // 开始
                    case Ascii.ENQ:
                        ack();
                        state = State.START;
                        lisDataHandler = new ShyDataHandler();
                        break;
                    // 确认 不处理
                    case Ascii.ACK:
                        break;

                    // 接收数据进行处理
                    case Ascii.STX:
                        state = State.DATA;
                        break;

                    // 结束
                    case Ascii.EOT:
                        state = State.END;

                        System.out.println("数据已经解析完成："+ JSON.toJSONString(lisDataHandler.getResults()));
                        if (shyDataLis != null){
                            shyDataLis.shyData(lisDataHandler.getResults());
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

    public void ack() throws IOException {

        send(new byte[]{Ascii.ACK});
    }

    public static interface ShyDataLis {

        void shyData(List<PersonResult> personResults);
    }

}
